using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Net;
using Microsoft.Xna.Framework.GamerServices;
using ZephyrisNet_WP7;


namespace Zephyris_Space_Mercs
{
    public class PeerNode
    {
        public long sessionID = 0;
        public ZephyrisNet_WP7.Helpers networkHelpers = new ZephyrisNet_WP7.Helpers();

        NetworkMainClass mobileNetwork = new NetworkMainClass();

        Thread THRD_RecieveLoop;
        Thread THRD_ParseLoop;
        Thread ThRD_lootSpawner;

        private Dictionary<Guid, Element> elementTable = new Dictionary<Guid, Element>();
        private Dictionary<IPEndPoint, PlayerEntity> playerTable = new Dictionary<IPEndPoint, PlayerEntity>();
        private Dictionary<IPEndPoint, PlayerEntity> playerTableTemp = new Dictionary<IPEndPoint, PlayerEntity>();

        private bool isHost = false;

        public bool IsHost
        {
            get 
            {
                isHost = mobileNetwork.IsSuperNode;
                return isHost; 
            }
            set 
            {
                isHost = value;
                mobileNetwork.IsSuperNode = isHost;
            }
        }

        private bool runNetwork;

        public bool RunNetwork
        {
            get { return runNetwork; }
            set { runNetwork = value; }
        }

        public bool Init()
        {
            runNetwork = mobileNetwork.StartNetwork();

            if (!runNetwork)
            {
                throw new Exception("Network Manager intialize failure");
            }

            THRD_RecieveLoop = new Thread(NetworkLoop);
            THRD_RecieveLoop.Start();

            return RunNetwork;
        }

        public bool Send(string data)
        {
            return mobileNetwork.SendP2P(data);
        }

        public bool Send(byte[] data)
        {
            return mobileNetwork.SendP2P(data);
        }

        public void NetworkLoop()
        {
            try
            {
                DataPacket dataPacket = new DataPacket();

                runNetwork = true;

                mobileNetwork.ReceiveP2P();

                while (runNetwork)
                {
                    dataPacket = mobileNetwork.GetDataPacket();

                    if (dataPacket.Data != "")
                    {
                        string[] dataIn = dataPacket.Data.Split(':');
                        string command = dataIn[0];
                        string[] parameters = null;

                        if (dataIn.Length > 1)
                        {
                            parameters = dataIn[1].Split('|');
                        }

                        switch (command)
                        {
                            case "INIT":
                                if (isHost)
                                {
                                    mobileNetwork.SendP2P("SEID:" + sessionID.ToString());
                                    //networkManager.SendP2P("INIT:" + sessionID.ToString());
                                }
                                break;

                            case "SEID":
                                if (!isHost)
                                {
                                    if (sessionID == 0)
                                    {
                                        sessionID = long.Parse(parameters[0]);
                                    }
                                }
                                break;

                            case "PING":
                                mobileNetwork.SendP2P("PONG:");                                
                                break;

                            case "PONG":
                                Ping.SetPingTest();
                                break;

                            case "POSN":
                                PlayerEntity incomingPlayer = new PlayerEntity(Guid.Parse(parameters[0]));

                                incomingPlayer.pos.X = float.Parse(parameters[1]);
                                incomingPlayer.pos.Y = float.Parse(parameters[2]);
                                incomingPlayer.pos.Z = float.Parse(parameters[3]);

                                incomingPlayer.rotQuat.X = float.Parse(parameters[4]);
                                incomingPlayer.rotQuat.Y = float.Parse(parameters[5]);
                                incomingPlayer.rotQuat.Z = float.Parse(parameters[6]);
                                incomingPlayer.rotQuat.W = float.Parse(parameters[7]);

                                incomingPlayer.drawShieldFlash = Convert.ToBoolean(int.Parse(parameters[8]));
                                incomingPlayer.drawArmourFlash = Convert.ToBoolean(int.Parse(parameters[9]));

                                Game1.UpdatePlayer(incomingPlayer);

                                break;

                            case "BULT":
                                BulletObject incomingBullet = new BulletObject();

                                incomingBullet.ownerId = Guid.Parse(parameters[0]);

                                incomingBullet.pos.X = float.Parse(parameters[1]);
                                incomingBullet.pos.Y = float.Parse(parameters[2]);
                                incomingBullet.pos.Z = float.Parse(parameters[3]);

                                incomingBullet.rot.X = float.Parse(parameters[4]);
                                incomingBullet.rot.Y = float.Parse(parameters[5]);
                                incomingBullet.rot.Z = float.Parse(parameters[6]);
                                incomingBullet.rot.W = float.Parse(parameters[7]);

                                incomingBullet.bulletType = (BulletObject.BulletType)Enum.Parse(typeof(BulletObject.BulletType), parameters[8], false);
                                incomingBullet.damage = float.Parse(parameters[9]);
                                incomingBullet.velocity = float.Parse(parameters[10]);

                                Game1.UpdateBullet(incomingBullet);

                                break;
                                

                        }
                    }

                }
            }
            catch (Exception ex)
            {
                runNetwork = false;
                throw ex;
            }
            
        }

    }
}
